import { createSlice,PayloadAction } from '@reduxjs/toolkit';
import { ComponentPropsType } from '../../components/QuestionComponents/index.ts';
// import {produce} from 'immer'   createSlice 已经内置了 Immer，不需要手动使用 produce
import { getNextSeletedId,insertNewComponent } from './util.ts'
import { nanoid } from 'nanoid';
// import cloneDeep from 'lodash.clonedeep';
import { arrayMove } from '@dnd-kit/sortable'; 
export type ComponentInfoType = {
    fe_id: string
    type:  string
    title: string
    isHidden?: boolean
    isLocked?: boolean
    props: ComponentPropsType  // 不同组件的属性是不一样的，把他合并起来
}

export type ComponentsStateType = { // 当前模块下定义的列表
    selectedId: string,
    componentList: Array<ComponentInfoType>
    copiedComponent: ComponentInfoType | null
}

const INIT_STATE: ComponentsStateType = {
    selectedId:'',
    componentList:[],
    // 其他扩展
    copiedComponent:null
}

export const componentsSlice = createSlice({
    name: 'components',
    initialState: INIT_STATE,
    reducers: {
        // 重置所有组件
        resetComponents: (state: ComponentsStateType, action: PayloadAction<ComponentsStateType>) => {
            return action.payload
        },

        // 修改 selectedId
        // changeSelectedId: produce((draft: ComponentsStateType, action: PayloadAction<string>) => {
        //  改善返回新的state 不能修改 state
        //     draft.selectedId = action.payload
        // }),
        changeSelectedId: (state:ComponentsStateType, action: PayloadAction<string>) => {
            state.selectedId = action.payload;
        },

        // 添加新组建
        addComponent: (state:ComponentsStateType,action:PayloadAction<ComponentInfoType>) =>{
            const newComponent = action.payload
            insertNewComponent(state,newComponent)
        },

        // 修改组件属性--这个方法要放在Edit/ComponentProp.tsx文件中使用
        changeComponentProps:(state:ComponentsStateType,action:PayloadAction<{ fe_id:string,  newProps:ComponentPropsType}>)=>{
            //解构的内容要和右边这两个字段保持一致 <{ fe_id:string,  newProps:ComponentPropsType}>
            const { fe_id, newProps } = action.payload
            // 找到当前要修改的组件
            const curComp = state.componentList.find(v=>v.fe_id === fe_id)
            // console.log('当前组件curComp',curComp);
            if(curComp){
                // 赋值方式1、
                // curComp.props = newProps
                // 赋值方式2、
                curComp.props = {
                    ...curComp.props,
                    ...newProps
                }
            }
        },

        // 删除选中的组件
        removeSelectedComponent:(state:ComponentsStateType)=>{
            const { componentList = [], selectedId: removeId } = state
            // 重新计算 selectedId，让删除当前的，后面紧挨着的接着高亮选中
            const newSelectedId = getNextSeletedId(removeId,componentList)
            state.selectedId = newSelectedId 
            const index = componentList.findIndex(c =>c.fe_id === removeId)
            componentList.splice(index,1)
        },

        // 隐藏和显示组件
        changeComponentHidden:(state:ComponentsStateType,action: PayloadAction<{fe_id: string, isHidden: boolean}>) =>{
            const {  componentList = [] } = state
            const { fe_id, isHidden } = action.payload
            // 重新计算
            let newSelectedId = ''
            if(isHidden){// 隐藏
                newSelectedId = getNextSeletedId(fe_id,componentList)
            }else{
                newSelectedId = fe_id
            }
            state.selectedId = newSelectedId 
            const curComp = componentList.find(c => c.fe_id === fe_id)
            if(curComp){
                curComp.isHidden = isHidden
            }
        },

        // 锁定/解锁 组件
        toggleComponentLocked:(state:ComponentsStateType,action: PayloadAction<{fe_id:string}>)=>{
            const {  componentList = [] } = state
            const { fe_id } = action.payload
            const curComp = componentList.find(c => c.fe_id === fe_id)
            if(curComp){
                curComp.isLocked = !curComp.isLocked
            }
        },

        // 拷贝复制
        copySelectedComponent:(state:ComponentsStateType)=>{
            const {  selectedId,componentList = [] } = state
            const selectedComponent = componentList.find(c =>c.fe_id === selectedId)
            if(selectedComponent == null) return
            // 深拷贝一份
            // state.copiedComponent = cloneDeep(selectedComponent)
            state.copiedComponent = JSON.parse(JSON.stringify(selectedComponent))
        },

        // 粘贴事件
        pasteCopiedComponent:(state:ComponentsStateType)=>{
            const { copiedComponent } = state
            if(copiedComponent == null) return

            // 要把fe_id修改了，如若不修改会和之前深拷贝的数据id一样了，起冲突了,id是不能一样的
            copiedComponent.fe_id = nanoid()
            // 插入copiedComponent
            insertNewComponent(state,copiedComponent)
        },

        // 选中上一个
        selectPrevComponent:(state:ComponentsStateType)=>{
            const { selectedId, componentList } = state
            const selectedIndex = componentList.findIndex(c =>c.fe_id === selectedId)

            if(selectedIndex < 0) return // 未选中
            if(selectedIndex <= 0) return // 已经选中第一个，无法再向上选中

            state.selectedId = componentList[selectedIndex - 1].fe_id
        },

        // 选中上一个
        selectNextComponent:(state:ComponentsStateType)=>{
            const { selectedId, componentList } = state
            const selectedIndex = componentList.findIndex(c =>c.fe_id === selectedId)

            if(selectedIndex < 0) return // 未选中
            if(selectedIndex +1 === componentList.length) return // 已经选中最后一个，无法再向下选中

            state.selectedId = componentList[selectedIndex + 1].fe_id
        },

        // 修改组件标题
        changeComponentTitle:(state:ComponentsStateType,action:PayloadAction<{fe_id:string,title:string}>)=>{
            const { title,fe_id } = action.payload
            const curComp = state.componentList.find(c =>c.fe_id === fe_id)
            if(curComp) curComp.title = title
        },

        // 移动组件位置
        moveComponent:(state:ComponentsStateType,action:PayloadAction<{oldIndex:number,newIndex:number}>)=>{
            const { componentList: curComponentList } = state
            const { oldIndex,newIndex } = action.payload

            state.componentList = arrayMove(curComponentList,oldIndex,newIndex)
        }
    }
})

export const { 
    resetComponents,
    changeSelectedId,
    addComponent,
    changeComponentProps,
    removeSelectedComponent,
    changeComponentHidden,
    toggleComponentLocked,
    copySelectedComponent, //在 EditToolbar里面引用
    pasteCopiedComponent,
    selectPrevComponent,
    selectNextComponent,
    changeComponentTitle,
    moveComponent
    
} = componentsSlice.actions

export default componentsSlice.reducer
